[IA64] more tlb flush when vcpu migration between pcpu.
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Wed, 5 Jul 2006 15:59:40 +0000 (09:59 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Wed, 5 Jul 2006 15:59:40 +0000 (09:59 -0600)
When vcpu is migrated to another pcpu and then it returns to the first
pcpu, VHPT and mTLB must also be flushed.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/ia64/xen/domain.c
xen/include/asm-ia64/domain.h

index 918af07a32f8fd313afa229bf36108d41c0dc66f..8ffab2699240c378bb93a647939f346c6b41cb4c 100644 (file)
@@ -93,25 +93,32 @@ DEFINE_PER_CPU(int *, current_psr_ic_addr);
 
 static void flush_vtlb_for_context_switch(struct vcpu* vcpu)
 {
-       int last_vcpu_id =
-               vcpu->domain->arch.last_vcpu[smp_processor_id()].vcpu_id;
+       int cpu = smp_processor_id();
+       int last_vcpu_id = vcpu->domain->arch.last_vcpu[cpu].vcpu_id;
+       int last_processor = vcpu->arch.last_processor;
 
-       if (is_idle_domain(vcpu->domain) || last_vcpu_id == vcpu->vcpu_id)
-               return;
-       vcpu->domain->arch.last_vcpu[smp_processor_id()].vcpu_id =
-               vcpu->vcpu_id;
-       if (last_vcpu_id == INVALID_VCPU_ID) 
+       if (is_idle_domain(vcpu->domain))
                return;
-
-       // if the vTLB implementation was changed,
-       // the followings must be updated either.
-       if (VMX_DOMAIN(vcpu)) {
-               // currently vTLB for vt-i domian is per vcpu.
-               // so any flushing isn't needed.
-       } else {
-               vhpt_flush();
+       
+       vcpu->domain->arch.last_vcpu[cpu].vcpu_id = vcpu->vcpu_id;
+       vcpu->arch.last_processor = cpu;
+
+       if ((last_vcpu_id != vcpu->vcpu_id &&
+            last_vcpu_id != INVALID_VCPU_ID) ||
+           (last_vcpu_id == vcpu->vcpu_id &&
+            last_processor != cpu &&
+            last_processor != INVALID_PROCESSOR)) {
+
+               // if the vTLB implementation was changed,
+               // the followings must be updated either.
+               if (VMX_DOMAIN(vcpu)) {
+                       // currently vTLB for vt-i domian is per vcpu.
+                       // so any flushing isn't needed.
+               } else {
+                       vhpt_flush();
+               }
+               local_flush_tlb_all();
        }
-       local_flush_tlb_all();
 }
 
 void schedule_tail(struct vcpu *prev)
@@ -298,6 +305,7 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
            v->arch.starting_rid = d->arch.starting_rid;
            v->arch.ending_rid = d->arch.ending_rid;
            v->arch.breakimm = d->arch.breakimm;
+           v->arch.last_processor = INVALID_PROCESSOR;
        }
 
        return v;
index 32e3d13dc63a1af7b349432e186221118d5eb2c0..afaa40150b22c7dc58230347bbeb80012697c054 100644 (file)
@@ -171,6 +171,9 @@ struct arch_vcpu {
     int mode_flags;
     fpswa_ret_t fpswa_ret;     /* save return values of FPSWA emulation */
     struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
+
+#define INVALID_PROCESSOR       INT_MAX
+    int last_processor;
 };
 
 #include <asm/uaccess.h> /* for KERNEL_DS */